import * as PIXI from 'pixi.js'
import QRCode from 'qrcode'
import res from '@/res'
// eslint-disable-next-line camelcase
import HarmonyOS_Sans_SC_Regular_full from '../assets/font/HarmonyOS_Sans_SC_Regular_full.ttf'
import { getH5URL } from './common'
let instance = null

/**
 * 图片合成类
 */
export default class Composite {
  constructor ({
    el = null,
    width = 750,
    height = 1333
  } = {}) {
    this.width = width
    this.height = height
    this.app = this.createApp(width, height)
    this.stage = this.app.stage
  }

  createApp (width, height) {
    if (instance) return instance
    const app = new PIXI.Application({
      width: width,
      height: height,
      antialias: true,
      backgroundAlpha: 0
    })
    instance = app
    return app
  }

  /**
   * 合成图片
   * @param assets
   * @param user
   * @returns {Promise<{showImage: string, saveImage: string}>}
   */
  async compose ({ assets = [], content = null, from = '匿名' } = {}) {
    this.assets = assets
    this.content = content
    this.from = from
    // 加载资源
    this.resources = await this.loadAssets(assets)
    // 加载字体
    PIXI.Assets.addBundle('fonts', {
      HarmonyOS_Sans_SC_Regular_full
    })
    await PIXI.Assets.loadBundle('fonts')

    // 合成的内容
    const container = new PIXI.Container()
    this.stage.addChild(container)

    const subContainer = new PIXI.Container()

    // 标题
    const title = this.createSpirte('title', {
      x: 108,
      y: 86
    })
    // 用户上传图片
    const pic = this.createSpirte('pic', {
      x: this.width / 2,
      y: title.y + title.height + 49
    })
    pic.width = 310 / pic.height * pic.width
    pic.height = 310
    pic.anchor.set(0.5, 0)

    const mask = new PIXI.Graphics()
    mask.beginFill(0x000000)
    mask.drawRect(46, pic.y, this.width - 92, 310)
    mask.endFill()
    pic.mask = mask

    const textContainer = new PIXI.Container()
    const textWidth = 615
    textContainer.position.set(67, pic.height + pic.y + 24)
    const text = new PIXI.Text(`${this.content}`, {
      fill: ['#6f5b5c'],
      fontFamily: 'HarmonyOS_Sans_SC_Regular_full',
      fontSize: 21.81,
      lineHeight: 30.6,
      wordWrap: true,
      wordWrapWidth: textWidth,
      breakWords: true,
      textIndent: 32
    })
    const textMinGraphic = new PIXI.Graphics()
    textMinGraphic.beginFill(0x000000, 0.5)
    textMinGraphic.drawRect(0, 0, textWidth, Math.max(27.08 * 3, text.height))
    textMinGraphic.endFill()
    textMinGraphic.alpha = 0
    textContainer.addChild(textMinGraphic, text)

    const sign = new PIXI.Text(`——来自“${this.from}”`, {
      fill: ['#6f5b5c'],
      fontFamily: 'HarmonyOS_Sans_SC_Regular_full',
      fontSize: 24.81,
      lineHeight: 25.6,
      wordWrap: true,
      wordWrapWidth: textWidth,
      breakWords: true
    })
    sign.anchor.set(1, 0)
    sign.position.set(textContainer.width + textContainer.x, textContainer.y + textContainer.height + 33)

    const icon = this.createSpirte('icon', {
      x: 71,
      y: sign.y + sign.height + 41
    })

    const qrcode = await this.createQrcode(getH5URL(), {})
    qrcode.position.set(516, icon.y + 10)
    qrcode.width = qrcode.height = 147
    subContainer.addChild(title, pic, mask, textContainer, sign, icon, qrcode)
    const contentHeight = subContainer.height + 45 + 86
    const bgColor = new PIXI.Graphics()
    bgColor.beginFill(0xffffff)
    bgColor.drawRect(0, 0, this.width, contentHeight)
    bgColor.endFill()

    // 贴图
    const bg = this.createSpirte('bg', {
      x: 0,
      y: 0,
      width: this.width,
      height: contentHeight
    })
    container.addChild(bgColor, bg, subContainer)

    const saveImage = await this.app.renderer.extract.image(container, 'image/jpeg')
    return {
      saveImage: saveImage.src
    }
  }

  /**
   * 创建精灵图片
   * @param name
   * @param options
   * @returns {Sprite}
   */
  createSpirte (name, options = null) {
    const newSprite = PIXI.Sprite.from(this.resources[name])
    if (options) {
      for (const k in options) {
        newSprite[k] = options[k]
      }
    }
    return newSprite
  }

  // 创建二维码
  createQrcode (url, options) {
    return new Promise((resolve, reject) => {
      QRCode.toCanvas(url, options, (err, canvas) => {
        if (err) {
          reject(err)
        } else {
          const baseTexture = new PIXI.BaseTexture(canvas)
          const texture = new PIXI.Texture(baseTexture)
          const qrcode = new PIXI.Sprite(texture)
          resolve(qrcode)
        }
      })
    })
  }

  /**
   * 加载资源
   * @param assets
   * @returns {Promise<unknown>}
   */
  loadAssets (assets = []) {
    const loader = PIXI.Assets
    const keyArr = []
    assets = [...assets, ...[{
      name: 'bg',
      url: res.compose.root.composePureBg
    },
    {
      name: 'title',
      url: res.compose.root.composePureTitle
    },
    {
      name: 'icon',
      url: res.compose.root.composePureIcon
    }]]
    assets.forEach(item => {
      loader.add(item.name, item.url)
      keyArr.push(item.name)
    })
    return loader.load(keyArr)
  }
}
